/**
* @file string_common.h
* @brief 提供字符串与其他类型的转换
* @author chenxiaole
* @version 1.0.0
* @date 2018-03-27
*/
#ifndef _COMMON_STRING_COMMON_H_
#define _COMMON_STRING_COMMON_H_

#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <sstream>
#include <errno.h>
#include <string.h>
#include <vector>
#include <stdio.h>

namespace common
{

	inline std::string ToString( const std::string &str ) { return str; }
	inline std::string ToString( const uint64_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const int64_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const uint32_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const int32_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const uint16_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const int16_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const int8_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const uint8_t& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const double& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const float& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	inline std::string ToString( const bool& val ) { std::stringstream ss; ss << val; std::string res; ss >> res; return res; }
	template<typename T>
	std::string ToString( const T& t )
	{		
			return t.ToString( );
	}



	inline bool FromString( const std::string &str, std::string &val ) { val = str; return true; }
	inline bool FromString( const std::string &str, uint64_t &val ) { bool ret = sscanf( str.c_str( ), "%llu", &val ) == 1; if ( !ret ) val = 0; return ret; }
	inline bool FromString( const std::string &str, int64_t &val ) { bool ret = sscanf( str.c_str( ), "%lld", &val ) == 1; if (!ret)val = 0;return ret; }
	inline bool FromString( const std::string &str, uint32_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > UINT_MAX || v < 0 ) { val = 0; return false; } else { val = ( uint32_t )v; return true; } }
	inline bool FromString( const std::string &str, int32_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > INT_MAX || v < INT_MIN ) { val = 0; return false; } else { val = ( int32_t )v; return true; } }
	inline bool FromString( const std::string &str, uint16_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > USHRT_MAX || v < 0 ) { val = 0; return false; } else { val = ( uint16_t )v; return true; } }
	inline bool FromString( const std::string &str, int16_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > SHRT_MAX || v < SHRT_MIN ) { val = 0; return false; } else { val = ( int16_t )v; return true; } }
	inline bool FromString( const std::string &str, uint8_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > UCHAR_MAX || v < 0 ) { val = 0; return false; } else { val = ( uint8_t )v; return true; } }
	inline bool FromString( const std::string &str, int8_t &val ) { int64_t v; if ( FromString( str, v ) == false || v > SCHAR_MAX || v < SCHAR_MIN ) { val = 0; return false; } else { val = ( int8_t )v; return true; } }
	inline bool FromString( const std::string &str, double &val ) { bool ret = sscanf( str.c_str( ), "%lf", &val ) == 1; if ( !ret ) val = 0.0; return ret; }
	inline bool FromString( const std::string &str, float &val ) { bool ret = sscanf( str.c_str( ), "%f", &val ) == 1; if ( !ret ) val = 0.0f; return ret; }
	inline bool FromString( const std::string &str, bool &val ) { val = ( ( str == "1" ) || ( str == "true" ) ); return true; }
	template<typename T>
	bool FromString( const std::string& str, T& t )
	{
			return t.FromString( str );
	}

	template<typename T>
	void SplitString( const std::string& str, const std::string& separator, std::vector<T>& result )
	{
		result.clear( );
		std::string::size_type cur_pos = 0;
		std::string::size_type new_pos = 0;
		while ( ( new_pos = str.find( separator, cur_pos ) ) != std::string::npos )
		{
			if ( new_pos - cur_pos > 0 )
			{
				std::string sub_str = str.substr( cur_pos, new_pos - cur_pos );
				T value;
				FromString( sub_str, value );
				result.push_back( value );
			}
			cur_pos = new_pos + separator.size( );
		}
		if ( cur_pos < str.size( ) )
		{
			std::string sub_str = str.substr( cur_pos, str.size( ) - cur_pos );
			T value;
			FromString( sub_str, value );
			result.push_back( value );
		}
	}

	typedef std::vector< std::string > StringTokens;
}

#endif
